home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl2 / demos / subtexture.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  6.3 KB  |  272 lines

  1. /* Copyright (c) Silicon Graphics, Inc. 1996 */
  2.  
  3. /*    subtexture.c
  4.  *    A program to demonstrate the use of the EXT_subtexture 
  5.  *    extention. It reads an image and texture maps it onto a polygon 
  6.  *    in the left half of the window. It then redefines a subtexture 
  7.  *    cut out of the middle of the image and maps the resulting texture
  8.  *    to the same polygon and displays it in the right half of the window.
  9.  * 
  10.  *    Escape key            - exit the program
  11.  */
  12. #include <GL/gl.h>
  13. #include <GL/glu.h>
  14. #include <GL/glut.h>
  15.  
  16. #include <math.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <unistd.h>
  20. #include <malloc.h>
  21.  
  22. #include "rgbImageFile.h"    /* should be in ../../include */
  23.  
  24. /*  Function Prototypes  */
  25.  
  26. GLvoid  initgfx( GLvoid );
  27. GLvoid  drawScene( GLvoid );
  28. GLvoid  reshape( GLsizei, GLsizei );
  29. GLvoid  keyboard( GLubyte, GLint, GLint );
  30.  
  31. GLvoid createSubImage( void );
  32. GLuint nearestPower( GLuint );
  33.  
  34. void printHelp( char * );
  35.  
  36. int getrenderer( char * );
  37. int getversion( char * );
  38.  
  39. /* Global Definitions */
  40.  
  41. /* The texel offsets and the dimensions of the subimages 
  42.  *      must be multiples of 32. 
  43.  */
  44. #define SUBSIZE    128
  45.  
  46. #define KEY_ESC    27    /* ascii value for the escape key */
  47.  
  48. /* Global Variables */
  49.  
  50. static GLubyte        *image, *sImage, subImage[SUBSIZE*SUBSIZE*4];
  51. static GLsizei        winWidth, winHeight;
  52. static GLsizei        sWidth, sHeight;
  53.  
  54. static GLint         subx, suby;
  55. static GLint         subwidth, subheight;
  56.  
  57. GLvoid
  58. main( int argc, char *argv[] )
  59. {
  60.     int    imgWidth, imgHeight;
  61.  
  62.     glutInit( &argc, argv );
  63.  
  64.  
  65.     if (argc < 2) {
  66.         fprintf (stderr, "usage: %s <imageFileName>\n", argv[0]);
  67.         exit (1);
  68.     }
  69.     image = (GLubyte *) rgbReadImageFile(argv[1], &imgWidth, &imgHeight);
  70.  
  71.     sWidth = nearestPower( imgWidth );
  72.     sHeight = nearestPower( imgHeight );
  73.     winWidth = sWidth * 2;
  74.     winHeight = sHeight;
  75.     if ( sWidth == imgWidth && sHeight == imgHeight ) {
  76.         sImage = image;
  77.     } else {
  78.         sImage = (GLubyte *)malloc( sHeight*sWidth*4*sizeof(GLubyte) );
  79.         gluScaleImage( GL_RGBA, 
  80.             imgWidth, imgHeight, GL_UNSIGNED_BYTE, image, 
  81.             sWidth, sHeight, GL_UNSIGNED_BYTE, sImage );
  82.     }
  83.  
  84.     /* calculate the offsets and size for the subimage */
  85.     subwidth = (sWidth <= SUBSIZE) ? sWidth/2 : SUBSIZE;
  86.     subheight = (sHeight <= SUBSIZE) ? sHeight/2 : SUBSIZE;
  87.     subx =  sWidth/2 - subwidth/2;
  88.     if (subx < 0) subx = 0;
  89.     suby =  sHeight/2 - subheight/2;
  90.     if (suby < 0) suby = 0;
  91.  
  92.     glutInitWindowSize( 4, 4 );
  93.     glutInitWindowSize( winWidth, winHeight ); 
  94.     glutInitDisplayMode( GLUT_RGBA );
  95.     glutCreateWindow( argv[0] );
  96.     
  97.     initgfx();
  98.  
  99.     glutKeyboardFunc( keyboard );
  100.     glutReshapeFunc( reshape );
  101.     glutDisplayFunc( drawScene ); 
  102.  
  103.     printHelp( argv[0] );
  104.  
  105.      glutMainLoop();
  106. }
  107.     
  108.         
  109. GLvoid
  110. printHelp( char *progname )
  111. {
  112.     fprintf(stdout, "\n%s - uses subtexture extension to redefine "
  113.         "a subimage in the middle\nof an images\n\n"
  114.         "Escape key                - exit the program\n",
  115.         progname);
  116. }
  117.  
  118. void
  119. initgfx( void )
  120. {
  121.     if (!glutExtensionSupported("GL_EXT_subtexture") &&
  122.         !(getrenderer("RE") && getversion("Irix 5.3"))) {
  123.         fprintf( stderr,
  124.            "GL_EXT_subtexture not supported on this machine\n");
  125.     }
  126.  
  127.     glEnable(GL_TEXTURE_2D);
  128.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  129.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  130.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  131.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  132.  
  133.     createSubImage();
  134. }
  135.  
  136. /* Compute the nearest power of 2 number. */
  137. GLuint 
  138. nearestPower( GLuint value )
  139. {
  140.     int i = 1;
  141.  
  142.     if (value == 0) return -1;    /* Error! */
  143.     for (;;) {
  144.         if (value == 1) return i;
  145.         else if (value == 3) return i*4;
  146.         value >>= 1; i *= 2;
  147.     }
  148. }
  149.  
  150. /*  Pass the name of the desired renderer.
  151.  *  Returns 1 if this is the desired renderer, 0 otherwise.
  152.  */
  153. int
  154. getrenderer(char *r)
  155. {
  156.     const GLubyte *s;
  157.  
  158.     s = glGetString( GL_RENDERER );
  159.     if ( !s || *s == '\0' ) return 0;
  160.     return( strstr(s,r) == 0 ) ? 0 : 1;
  161. }
  162.  
  163. /*  Pass the name of the desired version.
  164.  *  Returns 1 if this is the desired version, 0 otherwise.
  165.  */
  166. int
  167. getversion(char *v)
  168. {
  169.     const GLubyte *s;
  170.  
  171.     s = glGetString( GL_VERSION );
  172.     if ( !s || *s == '\0' ) return 0;
  173.     return( strstr(s,v) == 0 ) ? 0 : 1;
  174. }
  175.  
  176. GLvoid 
  177. keyboard( GLubyte key, GLint x, GLint y )
  178. {
  179.     switch (key) {
  180.     case KEY_ESC:    /* Exit whenever the Escape key is pressed */
  181.         exit(0);
  182.     }
  183. }
  184.  
  185. GLvoid
  186. reshape( GLsizei width, GLsizei height )
  187. {
  188.     /* make sure window size is odd */
  189.     winWidth = width;
  190.     winHeight = height;
  191.  
  192.     /* Create the first viewport - the left half of the window */
  193.     glViewport( 0, 0, winWidth/2, winHeight );
  194.  
  195.     glMatrixMode( GL_PROJECTION );
  196.     glLoadIdentity();
  197.     gluOrtho2D( 0.0, (GLdouble) winWidth-1, 0.0, (GLdouble) winHeight-1 );
  198.     glMatrixMode( GL_MODELVIEW );
  199.     glLoadIdentity();
  200.     glTranslatef( 0.375, 0.375, 0.0 );
  201. }
  202.     
  203. void 
  204. createSubImage(void)
  205. {
  206.     int i, j;
  207.     GLubyte *img = subImage;
  208.  
  209.     for (j = 0; j < subheight/4 * subwidth; j++) {
  210.         *img++ = 0xff;
  211.         *img++ = 0x00;
  212.         *img++ = 0x00;
  213.         *img++ = 0xff;
  214.     }
  215.     for (j = 0; j < subheight/4 * subwidth; j++) {
  216.         *img++ = 0xff;
  217.         *img++ = 0x00;
  218.         *img++ = 0xff;
  219.         *img++ = 0x00;
  220.     }
  221.     for (j = 0; j < subheight/4 * subwidth; j++) {
  222.         *img++ = 0xff;
  223.         *img++ = 0xff;
  224.         *img++ = 0x00;
  225.         *img++ = 0x00;
  226.     }
  227.     for (j = 0; j < subheight/4 * subwidth; j++) {
  228.         *img++ = 0x00;
  229.         *img++ = 0xff;
  230.         *img++ = 0x00;
  231.         *img++ = 0xff;
  232.     }
  233. }
  234.  
  235. GLvoid
  236. drawScene( GLvoid )
  237. {
  238.     glClear( GL_COLOR_BUFFER_BIT );
  239.  
  240.     /* Create the first viewport - the left half of the window */
  241.     glViewport( 0, 0, winWidth/2, winHeight );
  242.  
  243.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sWidth, sHeight, 0,
  244.             GL_RGBA, GL_UNSIGNED_BYTE, sImage);
  245.     glBegin(GL_QUADS);
  246.         glTexCoord2f( 0, 0 ); glVertex2f( 0, 0 );
  247.         glTexCoord2f( 1, 0 ); glVertex2f( winWidth, 0 );
  248.         glTexCoord2f( 1, 1 ); glVertex2f( winWidth, winHeight );
  249.         glTexCoord2f( 0, 1 ); glVertex2f( 0, winHeight );
  250.     glEnd();
  251.  
  252.     /* Create the second viewport - right half of window */
  253.     glViewport( winWidth/2 + 1, 0, winWidth/2, winHeight );
  254.  
  255. #ifdef    GL_EXT_subtexture
  256.     /* pass NULL image (this is an extension) */
  257.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 
  258.         sWidth, sHeight, 0, 0, 0, NULL); /* format, type irrelevant */
  259.  
  260.     glTexSubImage2DEXT( GL_TEXTURE_2D, 0, 
  261.         subx, suby, subwidth, subheight,
  262.         GL_RGBA, GL_UNSIGNED_BYTE, subImage);
  263. #endif
  264.     glBegin(GL_QUADS);
  265.         glTexCoord2f( 0, 0 ); glVertex2f( 0, 0 );
  266.         glTexCoord2f( 1, 0 ); glVertex2f( winWidth, 0 );
  267.         glTexCoord2f( 1, 1 ); glVertex2f( winWidth, winHeight );
  268.         glTexCoord2f( 0, 1 ); glVertex2f( 0, winHeight );
  269.     glEnd();
  270.     glFlush();
  271. }
  272.